package multijoueur;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

import core.Coordonnees;
import core.Couleur;
import echiquier.Deplacement;

public class Protocole {

	private Protocole() {};
	
	/**
	 * Balise de fin d'un envoi
	 */
	public final static int BALISEFIN = 0;
	
	/**
	 * Envoi de couleurs
	 */
	public final static int COULEURBLANC = 1;
	public final static int COULEURNOIR = 2;
	
	/**
	 * Envoi type, struct, classe ou d'enum
	 */
	public final static int ENVOIENTIER = 10;
	
	public final static int ENVOICOULEUR = 20;
	//les coordonnées sont 3 entiers envoyé à la suite
	public final static int ENVOICOORDONNEES = 30;
	
	public final static int ENVOIDEPLACEMENT = 41;
	
	//**Méthodes de lecture**//
	
	/**
	 * Méthode de lecture d'un entier
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static int lireEntier(BufferedReader in) throws IOException {		
		int res;
		
		if (in.read() == ENVOIENTIER) {
			res = in.read();
			if (in.read() == BALISEFIN) {
				return res;
			} else {
				throw new IOException();
			}
		} else {
			throw new IOException();
		}
		
		
	}
	
	/**
	 * Méthode de lecture d'une couleur
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static Couleur lireCouleur(BufferedReader in) throws IOException {
		int res;
		if (in.read() == ENVOICOULEUR) {
			res  = in.read();
			if (in.read() == BALISEFIN) {
				if (res == COULEURBLANC)
					return Couleur.Blanc;
				else if (res == COULEURNOIR)
					return Couleur.Noir;
				else
					throw new IOException();
			} else {
				throw new IOException();
			}
		} else {
			throw new IOException();
		}
	}

	/**
	 * Méthode de lecture de coordonnées
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static Coordonnees lireCoordonnees(BufferedReader in) throws IOException {
		int x, y;
		
		if(in.read() == ENVOICOORDONNEES) {
			x = lireEntier(in);
			y = lireEntier(in);
			
			if (in.read() == BALISEFIN) {
				return new Coordonnees(x, y);
			} else {
				throw new IOException();
			}
		} else {
			throw new IOException();
		}
	}
	
	/**
	 * Méthode de lecture de déplacement
	 * @param in
	 * @return
	 * @throws IOException
	 */
	public static Deplacement lireDeplacement(BufferedReader in) throws IOException {
		Coordonnees coordSource, coordDest;
		
		if (in.read() == ENVOIDEPLACEMENT) {
			coordSource = lireCoordonnees(in);
			coordDest = lireCoordonnees(in);
			if (in.read() == BALISEFIN) {
				return new Deplacement(coordSource, coordDest);
			} else {
				throw new IOException();
			}
		} else {
			throw new IOException();
		}
	}

	//**Méthodes d'envoi**//
	/**
	 * Méthode d'envoi d'entier
	 * @param out
	 * @param i
	 */
	public static void envoiEntier(PrintWriter out, int i) {
		out.print(ENVOIENTIER);
		out.print(i);
		out.print(BALISEFIN);
	}
	
	/**
	 * Méthode d'envoi d'une couleur
	 * @param out
	 * @param couleur
	 */
	public static void envoiCouleur(PrintWriter out, Couleur couleur) {
		out.print(ENVOICOULEUR);
		if (couleur == Couleur.Blanc)
			out.print(COULEURBLANC);
		else
			out.print(Couleur.Noir);
		
		out.print(BALISEFIN);
	}
	
	/**
	 * Méthode d'envoi de coordonnées
	 * @param out
	 * @param coord
	 */
	public static void envoiCoordonnees(PrintWriter out, Coordonnees coord) {
		out.print(ENVOICOORDONNEES);
		envoiEntier(out, coord.x);
		envoiEntier(out, coord.y);
		out.print(BALISEFIN);
	}
	
	/**
	 * Méthode d'envoi de déplacement
	 * @param out
	 * @param dep
	 */
	public static void envoiDeplacement(PrintWriter out, Deplacement dep) {
		out.print(ENVOIDEPLACEMENT);
		envoiCoordonnees(out, dep.coordSource);
		envoiCoordonnees(out, dep.coordDestination);
		out.print(BALISEFIN);
	}

}
